
/*************
author:: libo
license:: MIT
*****************/
#include<tool/libcell_tools_view.h>
#include<Mesh/libcell_iterator.h>
#define iterator_v lib_cell_iterator_vertices
#define iterator_f lib_cell_iterator_faces
#define iterator_c lib_cell_iterator_cells
#define quote lib_cell_quote
//应该用红黑树代替prop
//**
void get_data_from_1dim_cell(Mesh*m,float **v,unsigned int **e)
{
//#ifdef MANIFOLD_REQUIRE
    if(m->dimension!=1||m->manifold_require==0)
    {
        printf("can't draw\n");
        return ;
    }
//#endif
    if(*v!=NULL)
    {
        free(*v);
    }
    *v=(float*)malloc(sizeof(float)*m->num_v(m)*3);
    memset(*v,0,sizeof(float)*m->num_v(m)*3);
    if(*e!=NULL)
    {
        free(*e);
    }
    *e=(unsigned int*)malloc(sizeof(unsigned int)*m->num_c(m)*2);
    memset(*e,0,sizeof(unsigned int)*m->num_c(m)*2);
    int i=0;
    int* temp_v_id=(int*)malloc(sizeof(int)*m->num_v(m));
    Int_RB_Tree *tree=(Int_RB_Tree*)malloc(sizeof(Int_RB_Tree));
    int_rb_tree_init(tree);
    for(auto iter=m->v_begin(m);iter!=m->v_end(m);iter++)
    {       
        for(int j=0;j<quote(iter)->point_size;j++)
        {
            (*v)[i*3+j]=quote(iter)->point[j];
        }
        temp_v_id[i]=i;
        //quote(iter)->prop=(void*)(&temp_v_id[i]);
        tree->insert(tree,quote(iter)->id,&temp_v_id[i]);
        i++; 
    }
    i=0;
    for(auto iter=m->c_begin(m);iter!=m->c_end(m);iter++)
    {
     
        for(auto iter1=m->cv_begin(m,*((template_c*)(quote(iter))));iter1!=m->cv_end(m,*((template_c*)(quote(iter))));iter1++)
        {
            (*e)[i]=*((int*)(tree->find(tree,quote(iter1)->id)));
           // (*e)[i]=*((int*)((*iter1).prop));
            i++;
        }

    }
    free(temp_v_id);
    //reset_v_prop(m);
    int_rb_tree_free(tree);

}
//二维流形可视化

//

//**********
void get_data_from_2dim_cell(Mesh* m,float**v,unsigned int**f)
{
//#ifdef MANIFOLD_REQUIRE
    if(m->dimension!=2)
    {
        printf("can't draw\n");
        return ;
    }
//#endif
    //要重排vertices id
    //***
    if((*v)!=NULL)
    {
        free((*v));
    }
    *v=(float*)malloc(sizeof(float)*m->num_v(m)*3);
    memset(*v,0,sizeof(float)*m->num_v(m)*3);
    int f_size=0;
    for(auto iter=m->c_begin(m);iter!=m->c_end(m);iter++)
    {
        f_size+=(((template_c*)(quote(iter)))->vertices_size+1);  
    }

	if((*f)!=NULL)
	{free((*f));
	}
    //int *temp_v_id=(int*)malloc(sizeof(int)*m->num_v(m));
    *f=(unsigned int*)malloc(sizeof(unsigned int)*f_size);
    memset(*f,0,sizeof(unsigned int)*f_size);
    int i=0;
    Int_RB_Tree *tree=(Int_RB_Tree*)malloc(sizeof(Int_RB_Tree));
    int_rb_tree_init(tree);

    int* temp_v_id=(int*)malloc(sizeof(int)*m->num_v(m));
    for(auto iter=m->v_begin(m);iter!=m->v_end(m);iter++)
    {       
        for(int j=0;j<((template_v*)(quote(iter)))->point_size;j++)
        {
            (*v)[i*3+j]=((template_v*)(quote(iter)))->point[j];
        //    temp_z+=(*v)[i*3+j]*(*v)[i*3+j];
        }
        temp_v_id[i]=i;
        tree->insert(tree,quote(iter)->id,&temp_v_id[i]);
        //((template_v*)(quote(iter)))->prop=(void*)(&temp_v_id[i]);
//       (*v)[i*3+2]=(float)temp_z/2.0;
 /*       if(iter->second->id==500)
        {
            (*v)[i*3+2]=0.6;
        }*/
        i++; 
    }
    i=0;
    for(auto iter=m->c_begin(m);iter!=m->c_end(m);iter++)
    {
        (*f)[i]=((template_c*)(quote(iter)))->vertices_size;
        i++;
        for(auto iter1=m->cv_begin(m,*((template_c*)(quote(iter))));iter1!=m->cv_end(m,*((template_c*)(quote(iter))));iter1++)
        {
            (*f)[i]=*((int*)(tree->find(tree,quote(iter1)->id))); 
            //(*f)[i]=*((int*)((*iter1).prop));
            i++;
        }
    }
    free(temp_v_id);
    //reset_v_prop(m);
    int_rb_tree_free(tree);
}
void get_data_from_cell(Mesh* m,float**v,unsigned int**f)
{
   
//#ifdef MANIFOLD_REQUIRE
    if(m->dimension==1||m->manifold_require==0)
    {
        get_data_from_1dim_cell(m,v,f);
    }
    else if(m->dimension==2)
    {
        get_data_from_2dim_cell(m,v,f);
    }
//#endif 

}
void  get_data_from_3dim_cell(Mesh* m,float** v,unsigned int** f,unsigned int* Data_rows,unsigned int* Data_index_rows)
{
    if(m->manifold_require==0)
    {
        return ;
    }
//#ifdef MANIFOLD_REQUIRE
    if(m->dimension!=3)
    {
        printf("can't draw\n");
        return ;
    }
//#endif
    //要重排vertices id
//**
    if((*v)!=0)
    {
        free((*v));
    }
    *v=(float*)malloc(sizeof(float)*m->num_v(m)*3);
    memset(*v,0,sizeof(float)*m->num_v(m)*3);
//注意此处的haslfaces的顺序
    m->external_cells_init_(m);

    
    int f_size=0,sum_c=0;

    template_hf* hf=NULL;
    for(Node* nit1=m->external_cells;nit1!=NULL;nit1=(Node*)(nit1->Next))
    {
        template_c* external_cell=(template_c*)(nit1->value);
        for(auto chfit=m->chf_begin(m,*external_cell);chfit!=m->chf_end(m,*external_cell);chfit++)
        {
            hf=quote(chfit);
            for(int j=0;j<hf->vertices_size;j++)
            {
                printf("%d ",hf->vertices[j]->id);
            } 
            printf("\n");
        //printf("size:%d\n",hf->vertices_size);
            f_size+=(hf->vertices_size+1);
            sum_c++;
        }
    }
    
    if((*f)!=0)
    {free((*f));
    }

    printf("hrer\n");
    //int *temp_v_id=(int*)malloc(sizeof(int)*m->num_v(m));
    *f=(unsigned int*)malloc(sizeof(unsigned int)*f_size);
    memset(*f,0,sizeof(unsigned int)*f_size);
    int i=0;
    int* temp_v_id=(int*)malloc(sizeof(int)*m->num_v(m));
    for(auto iter=m->v_begin(m);iter!=m->v_end(m);iter++)
    {       
        for(int j=0;j<3;j++)
        {
            (*v)[i*3+j]=((template_v*)(quote(iter)))->point[j];
        //    temp_z+=(*v)[i*3+j]*(*v)[i*3+j];
        }
        temp_v_id[i]=i;
        ((template_v*)(quote(iter)))->prop=(void*)(&temp_v_id[i]);
//       (*v)[i*3+2]=(float)temp_z/2.0;
 /*       if(iter->second->id==500)
        {
            (*v)[i*3+2]=0.6;
        }*/
        i++; 
    }
    i=0;

    printf("f_size:%d\n",f_size);
    for(Node* nit1=m->external_cells;nit1!=NULL;nit1=(Node*)(nit1->Next))
    {
        template_c* external_cell=(template_c*)(nit1->value);
        //for(Node* nit=external_cell->halffaces;nit!=NULL;nit=(Node*)(nit->Next))
        for(auto chfit=m->chf_begin(m,*external_cell);chfit!=m->chf_end(m,*external_cell);chfit++)
        {
            hf=quote(chfit);
            hf=m->s_opposite_halfface(hf);
            (*f)[i]=hf->vertices_size;
            i++;
            for(auto iter1=m->hfv_begin(m,*hf);iter1!=m->hfv_end(m,*hf);iter1++)
            {
                (*f)[i]=*((int*)((*iter1).prop));
                printf("%d ",(*f)[i]);
                i++;
            } 

            printf("\n");
        }
    }

   
    m->reset_v_prop(m,0);
    *Data_rows=m->num_v(m);

    *Data_index_rows=sum_c;
    
    free(temp_v_id);
}
void get_lines_data_from_2dim_cell(Mesh*m ,float **v ,unsigned int **e)
{
    SAFE_FREE(*v);SAFE_FREE(*e);
    *v=(float*)malloc(sizeof(float)*3*m->num_v(m));
    *e=(unsigned int*)malloc(sizeof(unsigned int)*2*m->num_f(m));
    int i=0;
    int* temp_v_id=(int*)malloc(sizeof(int)*m->num_v(m));
    Int_RB_Tree *tree=(Int_RB_Tree*)malloc(sizeof(Int_RB_Tree));
    int_rb_tree_init(tree);
    for(auto iter=m->v_begin(m);iter!=m->v_end(m);iter++)
    {
        (*v)[i*3+0]=quote(iter)->point[0];
        (*v)[i*3+1]=quote(iter)->point[1]; 
        (*v)[i*3+2]=quote(iter)->point[2];
        temp_v_id[i]=i;
        tree->insert(tree,quote(iter)->id,&(temp_v_id[i]));
        i++;
    } 
    i=0;
    for(auto iter=m->f_begin(m);iter!=m->f_end(m);iter++)
    {
        (*e)[i*2+0]=*((int*)(tree->find(tree,quote(iter)->vertices[0]->id)));
        (*e)[i*2+1]=*((int*)(tree->find(tree,quote(iter)->vertices[1]->id)));
        i++;
    }
    
    free(temp_v_id);
    int_rb_tree_free(tree);

}
